# -*- coding: utf-8 -*-# 
'''
Created on 2011-12-7

@author: qigang.llb
'''
import md5,os,time
import urllib,urllib2
import json,xml.dom.minidom
import logging
#from lib.request.ItemsSearchRequest import *
from request.ItemsSearchRequest import *

BASE_PATH = 'd:/'
logFormat = '[%(asctime)s] %(levelname)s %(message)s'
logFilename = 'bbk.log'
logLevel = logging.INFO
logging.basicConfig(level=logLevel,
    format=logFormat,
    filename=os.path.join(BASE_PATH,logFilename),
    filemode='a')

class TopClient:
    '''
    classdocs
    '''
    appkey = '12443826'
    secretKey = 'sandboxec3eed15f5f56fe3a35441592'
    gatewayUrl = "http://gw.api.taobao.com/router/rest"
    format = "json"
    gatewayUrl = 'http://gw.api.tbsandbox.com/router/rest';
    
    
    
    """ 是否打开入参check """
    checkRequest = False
    signMethod = "md5"
    apiVersion = "2.0"
    sdkVersion = "top-sdk-python-20120113"

    def __init__(self):
        self.checkRequest = False
        self.signMethod = "md5"
        self.apiVersion = "2.0"
        self.sdkVersion = "top-sdk-python-20120113"

    def setKeys(self,appkey,secretKey):
        self.appkey = appkey
        self.secretKey = secretKey

    def setGateWay(self,getwayurl):
        self.gatewayUrl = getwayurl

    def setFormat(self,format):
        self.format = format

    def setReq(self,objname):
        if globals().has_key(objname):
            constructor = globals()[objname]
            self.req = constructor()
        else:
            return 0

    def setReqFields(self,fields):
        if hasattr(self,"req"):
            self.req.setFields(fields)
        else:
            return 0

    def setQuerys(self,querylist):
        for query in querylist:
            if hasattr(self.req,query):
                getattr(self.req, query)(querylist[query].encode(encoding='utf-8'))

    def generateSign(self,params):
        pkeys = params.keys()
        pkeys.sort()
        stringToBeSigned = self.secretKey
        for pk in pkeys:
            if '@' != params[pk]:
                stringToBeSigned += pk+params[pk]
        stringToBeSigned += self.secretKey
        return md5.md5(stringToBeSigned).hexdigest().upper()
    
    def curl(self,url,postFields):
        postBody=urllib.urlencode(postFields)
        req = urllib2.Request(url, postBody)
        response = urllib2.urlopen(req)
        return response.read()

        
    """
    @return adc
    protected function curl($url, $postFields = null)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_FAILONERROR, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        if (is_array($postFields) && 0 < count($postFields))
        {
            $postBodyString = "";
            $postMultipart = false;
            foreach ($postFields as $k => $v)
            {
                if("@" != substr($v, 0, 1))//判断是不是文件上传
                {
                    $postBodyString .= "$k=" . urlencode($v) . "&"; 
                }
                else//文件上传用multipart/form-data，否则用www-form-urlencoded
                {
                    $postMultipart = true;
                }
            }
            unset($k, $v);
            curl_setopt($ch, CURLOPT_POST, true);
            if ($postMultipart)
            {
                curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
            }
            else
            {
                curl_setopt($ch, CURLOPT_POSTFIELDS, substr($postBodyString,0,-1));
            }
        }
        $reponse = curl_exec($ch);
        
        if (curl_errno($ch))
        {
            throw new Exception(curl_error($ch),0);
        }
        else
        {
            $httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            if (200 !== $httpStatusCode)
            {
                throw new Exception($reponse,$httpStatusCode);
            }
        }
        curl_close($ch);
        return $reponse;
    }

    """
        
    def execute(self,request=None,session=None):
        result={'code':0,'msg':''}
        if request is None:
            request = self.req
        if(self.checkRequest):
            try:
                request.check()
            except Exception,e:
                result = e
        #组装系统参数
        sysParams = {}
        sysParams["app_key"] = self.appkey
        sysParams["v"] = self.apiVersion
        sysParams["format"] = self.format
        sysParams["sign_method"] = self.signMethod
        sysParams["method"] = request.getApiMethodName()
        sysParams["timestamp"] = time.strftime("%Y-%m-%d %H:%M:%S")
        sysParams["partner_id"] = self.sdkVersion
        if session is not None:
            sysParams["session"]= session
        
        #获取业务参数
        apiParams = request.getApiParas()
        
        #签名
        apiParams.update(sysParams)
        sysParams["sign"] = self.generateSign(apiParams) 
        #系统参数放入GET请求串           
        requestUrl = self.gatewayUrl + "?"
        requestUrl += urllib.urlencode(sysParams)
        
        #发起HTTP请求
        try:
            resp = self.curl(requestUrl, apiParams)
        except Exception,e:
            logging.error("method: %s request: %s HTTP_ERROR_%s" %(sysParams["method"],requestUrl,e))
            result = e
            return result
        
        #解析TOP返回结果
        respWellFormed = False 
        if "json" == self.format:
            respObject = json.loads(resp)
            if respObject is not None:
                respWellFormed = True
        elif "xml" == self.format:
            respObject = xml.dom.minidom.parseString(resp)
            if respObject:
                respWellFormed = True
            
        #返回的HTTP文本不是标准JSON或者XML，记下错误日志
        if not respWellFormed:
            logging.error("%s,%s,HTTP_RESPONSE_NOT_WELL_FORMED %s" %(sysParams["method"],requestUrl,resp))
            result['code'] = 0
            result['msg'] = "HTTP_RESPONSE_NOT_WELL_FORMED"
            return result;
        
        #如果TOP返回了错误码，记录到业务错误日志中
        if "json" == self.format:
            if respObject.has_key('error_response'):
                logging.error("%s" % (resp))
        elif "xml" == self.format:
            if len(respObject.getElementsByTagName('error_response')) > 0:
                logging.error("%s" % (resp))       
        return respObject
    
    """
    public function execute($request, $session = null)
    {
        if($this->checkRequest) {
            try {
                $request->check();
            } catch (Exception $e) {
                $result->code = $e->getCode();
                $result->msg = $e->getMessage();
                return $result;
            }
        }
        //组装系统参数
        $sysParams["app_key"] = $this->appkey;
        $sysParams["v"] = $this->apiVersion;
        $sysParams["format"] = $this->format;
        $sysParams["sign_method"] = $this->signMethod;
        $sysParams["method"] = $request->getApiMethodName();
        $sysParams["timestamp"] = date("Y-m-d H:i:s");
        $sysParams["partner_id"] = $this->sdkVersion;
        if (null != $session)
        {
            $sysParams["session"] = $session;
        }

        //获取业务参数
        $apiParams = $request->getApiParas();

        //签名
        $sysParams["sign"] = $this->generateSign(array_merge($apiParams, $sysParams));

        //系统参数放入GET请求串
        $requestUrl = $this->gatewayUrl . "?";
        foreach ($sysParams as $sysParamKey => $sysParamValue)
        {
            $requestUrl .= "$sysParamKey=" . urlencode($sysParamValue) . "&";
        }
        $requestUrl = substr($requestUrl, 0, -1);

        //发起HTTP请求
        try
        {
            $resp = $this->curl($requestUrl, $apiParams);
        }
        catch (Exception $e)
        {
            $this->logCommunicationError($sysParams["method"],$requestUrl,"HTTP_ERROR_" . $e->getCode(),$e->getMessage());
            $result->code = $e->getCode();
            $result->msg = $e->getMessage();
            return $result;
        }

        //解析TOP返回结果
        $respWellFormed = false;
        if ("json" == $this->format)
        {
            $respObject = json_decode($resp);
            if (null !== $respObject)
            {
                $respWellFormed = true;
                foreach ($respObject as $propKey => $propValue)
                {
                    $respObject = $propValue;
                }
            }
        }
        else if("xml" == $this->format)
        {
            $respObject = @simplexml_load_string($resp);
            if (false !== $respObject)
            {
                $respWellFormed = true;
            }
        }

        //返回的HTTP文本不是标准JSON或者XML，记下错误日志
        if (false === $respWellFormed)
        {
            $this->logCommunicationError($sysParams["method"],$requestUrl,"HTTP_RESPONSE_NOT_WELL_FORMED",$resp);
            $result->code = 0;
            $result->msg = "HTTP_RESPONSE_NOT_WELL_FORMED";
            return $result;
        }

        //如果TOP返回了错误码，记录到业务错误日志中
        if (isset($respObject->code))
        {
            $logger = new LtLogger;
            $logger->conf["log_file"] = rtrim(TOP_SDK_WORK_DIR, '\\/') . '/' . "logs/top_biz_err_" . $this->appkey . "_" . date("Y-m-d") . ".log";
            $logger->log(array(
                date("Y-m-d H:i:s"),
                $resp
            ));
        }
        return $respObject;
    }

    """

     
    
    def exe(self,paramsArray):
        if paramsArray.has_keys("method"):
            raise "No api name passed"
        pass
    """
    public function exec($paramsArray)
    {
        if (!isset($paramsArray["method"]))
        {
            trigger_error("No api name passed");
        }
        $inflector = new LtInflector;
        $inflector->conf["separator"] = ".";
        $requestClassName = ucfirst($inflector->camelize(substr($paramsArray["method"], 7))) . "Request";
        if (!class_exists($requestClassName))
        {
            trigger_error("No such api: " . $paramsArray["method"]);
        }

        $session = isset($paramsArray["session"]) ? $paramsArray["session"] : null;

        $req = new $requestClassName;
        foreach($paramsArray as $paraKey => $paraValue)
        {
            $inflector->conf["separator"] = "_";
            $setterMethodName = $inflector->camelize($paraKey);
            $inflector->conf["separator"] = ".";
            $setterMethodName = "set" . $inflector->camelize($setterMethodName);
            if (method_exists($req, $setterMethodName))
            {
                $req->$setterMethodName($paraValue);
            }
        }
        return $this->execute($req, $session);
    }
}
    """

def getItemQ(querylist):
    c =TopClient()
    req =ItemsSearchRequest()
    req.setFields("num_iid,title,nick,pic_url,cid,price,type,delist_time,post_fee,score,volume")
    for query in querylist:
        if hasattr(req,query):
            getattr(req, query)(querylist[query][0])
    resp = c.execute(req)   
    return resp

if __name__ == '__main__':
    """
    fields="num_iid,title,nick,pic_url,cid,price,type,delist_time,post_fee,score,volume"
    tc = TopClient()
    tc.setKeys(appkey='12443826',secretKey='sandboxec3eed15f5f56fe3a35441592')
    tc.setGateWay('http://gw.api.tbsandbox.com/router/rest')
    tc.setFormat("json")
    tc.setReq("ItemsSearchRequest",fields)
    querylist={'setQ':['连衣裙',]}
    tc.setQuerys(querylist)
    resp = tc.execute()
    print resp
    """
    #querylist={'setQ':['连衣裙',]}
    st=u'\u8fde\u8863\u88d9'
    st=st.encode(encoding='utf-8')
    querylist={'setQ':[st,]}
    print getItemQ(querylist)